#include "stdafx.h"
#include "CReferenceCount.h"
#include "IPALDebuggingServices.h"
//
//extern IPALDebuggingServices * GetPALDebuggingServices();

#include "IThreadMonitor.h"
CReferenceCount::CReferenceCount():
	CReferenceCountBase()
{
	this->m_pThreadMonitor = NULL;
}

CReferenceCount::~CReferenceCount()
{
	this->ThreadCheck(L"Deletion called on different thread from first use");
	delete this;
}

XUINT32 CReferenceCount::AddRef()
{
	unsigned int newCount;
	this->AddRefPreCheck();
	this->ThreadCheck(L"AddRef called on different thread from first use");
	newCount = this->m_cReferences +1;
	this->m_cReferences = newCount;
	this->AddRefPostCheck(newCount);
	return newCount;
}

XUINT32 CReferenceCount::Release()
{
	unsigned int newCount;

	this->ReleasePreCheck();
	this->ThreadCheck(L"Release called on different thread from first use");
	newCount = this->m_cReferences - 1;
	this->m_cReferences = newCount;
	this->ReleasePostCheck(newCount);
	if ( !newCount && this )
		delete this;
	return newCount;
}

CReferenceCount & CReferenceCount::operator=( const CReferenceCount  & rhs)
{
	CReferenceCountBase::operator=(rhs);
	this->m_pThreadMonitor = rhs.m_pThreadMonitor;
	return *this;
}

void CReferenceCount::ThreadCheck( XCHAR * pszMessage )
{
	IThreadMonitor * pThreadMonitor = GetPALDebuggingServices()->GetThreadMonitor();
	pThreadMonitor->Resume();
	if ( this->m_pThreadMonitor )
	{
		TRACE_ENSURE2(m_pThreadMonitor == pThreadMonitor,L"pszMessage",pszMessage);
	}
	else
	{
		this->m_pThreadMonitor = pThreadMonitor;
	}
}
